package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.ExamRecord;
import com.atguigu.exam.entity.Paper;
import com.atguigu.exam.entity.PaperQuestion;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.mapper.PaperMapper;
import com.atguigu.exam.mapper.PaperQuestionMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.PaperQuestionService;
import com.atguigu.exam.service.PaperService;
import com.atguigu.exam.vo.AiPaperVo;
import com.atguigu.exam.vo.PaperVo;
import com.atguigu.exam.vo.RuleVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 试卷服务实现类
 */
@Slf4j
@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private PaperQuestionMapper paperQuestionMapper;

    @Autowired
    private PaperQuestionService paperQuestionService;

    @Autowired
    private ExamRecordMapper examRecordMapper;

    @Override
    public Paper getPaperDetailsById(Integer id) {
        Paper paper = baseMapper.selectById(id);
//        List<PaperQuestion> paperQuestions = paperQuestionMapper.selectList(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId, id));
//        List<Long> questionIds = paperQuestions.stream().map(PaperQuestion::getQuestionId).collect(Collectors.toList());
//        List<Question> questionList = new ArrayList<>();
//        questionIds.forEach(questionId -> {
//            Question questionDetailsById = questionMapper.selectByQuestionId(questionId);
//            questionList.add(questionDetailsById);
//        });

        List<Question> questionList = questionMapper.getQuestionListByPaperId(id);
        paper.setQuestions(questionList);
        return paper;
    }

    @Override
    public Paper createPaper(PaperVo paperVo) {
        //判断是否已存在同名的试卷
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, paperVo.getName()));
        if(exists){
            throw new ExamException(1002,"试卷名称已存在，请修改试卷名称");
        }
        //创建一个Paper对象
        Paper paper = new Paper();
        //复制相同的属性值
        BeanUtils.copyProperties(paperVo,paper);
        //设置试卷状态为草稿
        paper.setStatus("DRAFT");
        //获取paperVo中的map
        Map<Long, BigDecimal> questions = paperVo.getQuestions();
        //给试卷设置题目数量
        paper.setQuestionCount(questions.size());
        //计算试卷总分
        BigDecimal totalScore = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        //设置试卷总分
        paper.setTotalScore(totalScore);
        //调用自带的方法保存试卷
        baseMapper.insert(paper);

        //将Map<Integer, BigDecimal>中的转换为List<PaperQuestion>
        List<PaperQuestion> paperQuestionList = questions.entrySet().stream().map(entry -> new PaperQuestion(paper.getId(), entry.getKey(), entry.getValue())).collect(Collectors.toList());
        //调用PaperQuestionService中的批量保存方法
        paperQuestionService.saveBatch(paperQuestionList);
        return paper;
    }

    @Override
    public Paper updatePaper(Integer id, PaperVo paperVo) {
        Paper paper = baseMapper.selectById(id);
        if("PUBLISHED".equals(paper.getStatus())){
            throw new ExamException(1003,"发布状态的试卷不能被修改");
        }
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, paperVo.getName()).ne(Paper::getId, id));
        if(exists){
            throw new ExamException(1004,"试卷名称已存在，请修改试卷名称");
        }
        BeanUtils.copyProperties(paperVo,paper);
        paper.setUpdateTime(new Date());
        Map<Long, BigDecimal> questions = paperVo.getQuestions();
        paper.setQuestionCount(questions.size());
        BigDecimal totalScore = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(totalScore);
        baseMapper.updateById(paper);
        paperQuestionMapper.delete(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId,id));
        List<PaperQuestion> paperQuestionList = questions.entrySet().stream().map(entry -> new PaperQuestion(paper.getId(), entry.getKey(), entry.getValue())).collect(Collectors.toList());
        paperQuestionService.saveBatch(paperQuestionList);
        return paper;
    }

    @Override
    public void updatePaperStatus(Integer id, String status) {
        Long count = examRecordMapper.selectCount(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getExamId, id).eq(ExamRecord::getStatus, "进行中"));
        if (count > 0){
            throw new ExamException(1005,"试卷正在被考试，不能更新!");
        }
        baseMapper.update(null,new LambdaUpdateWrapper<Paper>().eq(Paper::getId,id).set(Paper::getStatus,status));
    }

    @Override
    public void deletePaperById(Integer id) {
        //并且试卷正在被考试，不能删除
        Long count = examRecordMapper.selectCount(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getExamId, id).eq(ExamRecord::getStatus, "进行中"));
        if (count > 0){
            //抛出异常
            throw new ExamException(1005,"试卷正在被考试，不能删除");
        }
        //调用自带的方法删除试卷
        baseMapper.deleteById(id);
        //删除中间表中的数据
        paperQuestionMapper.delete(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId,id));
    }

    @Override
    public Paper createPaperByAi(AiPaperVo aiPaperVo) {
//        判断是否存在同名试卷
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, aiPaperVo.getName()));
        if(exists){
            throw new ExamException(1003,"试卷名称已存在，请修改试卷名称");
        }
        
        // 创建题目ID到分数的映射
        Map<Long, BigDecimal> questionScoreMap = new HashMap<>();
        
        // 根据规则随机选择题目
        for (RuleVo rule : aiPaperVo.getRules()) {
            // 构建查询条件
            LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Question::getType, rule.getType().name());
            
            // 如果指定了分类，则添加分类条件
            if (rule.getCategoryIds() != null && !rule.getCategoryIds().isEmpty()) {
                queryWrapper.in(Question::getCategoryId, rule.getCategoryIds());
            }
            
            // 查询符合条件的所有题目
            List<Question> allQuestions = questionMapper.selectList(queryWrapper);
            
            // 随机选择指定数量的题目
            if (allQuestions.size() < rule.getCount()) {
                throw new ExamException(1006, "题库中符合条件的" + rule.getType().name() + "题目数量不足，需要" + rule.getCount() + "道，实际只有" + allQuestions.size() + "道");
            }
            
            // 随机打乱题目顺序
            Collections.shuffle(allQuestions);
            
            // 选择前count个题目
            List<Question> selectedQuestions = allQuestions.subList(0, rule.getCount());
            
            // 将选中的题目ID和分数添加到映射中
            BigDecimal score = BigDecimal.valueOf(rule.getScore());
            for (Question question : selectedQuestions) {
                questionScoreMap.put(question.getId(), score);
            }
        }
        
        // 构建PaperVo对象
        PaperVo paperVo = new PaperVo();
        paperVo.setName(aiPaperVo.getName());
        paperVo.setDescription(aiPaperVo.getDescription());
        paperVo.setDuration(aiPaperVo.getDuration());
        paperVo.setQuestions(questionScoreMap);
        
        // 调用现有方法创建试卷
        return createPaper(paperVo);
    }
}